package com.qiwenshare.file.controller;

import com.google.common.base.Strings;
import com.qiwenshare.common.result.RestResult;
import com.qiwenshare.file.component.FileDealComp;
import com.qiwenshare.file.domain.FileBean;
import com.qiwenshare.file.domain.UserFile;
import com.qiwenshare.file.domain.user.Role;
import com.qiwenshare.file.domain.user.UserBean;
import com.qiwenshare.file.dto.file.WOPIFileInfoDTO;
import com.qiwenshare.file.service.FileService;
import com.qiwenshare.file.service.UserFileService;
import com.qiwenshare.file.service.UserLoginInfoService;
import com.qiwenshare.file.service.UserService;
import com.qiwenshare.file.vo.file.FileDetailVO;
import com.qiwenshare.ufop.exception.operation.DownloadException;
import com.qiwenshare.ufop.exception.operation.UploadException;
import com.qiwenshare.ufop.factory.UFOPFactory;
import com.qiwenshare.ufop.operation.download.Downloader;
import com.qiwenshare.ufop.operation.download.domain.DownloadFile;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.util.IOTools;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

@Tag(name = "wopi", description = "该接口为wopi文件操作接口，主要用来做一些文档的编辑，浏览等。")
@RestController
@Slf4j
@RequestMapping({"/wopi"})
public class WOPIController {

    @Autowired
    UserFileService userFileService;

    @Autowired
    FileService fileService;

    @Autowired
    UserService userService;

    @Autowired
    UserLoginInfoService userLoginInfoService;

    @Autowired
    UFOPFactory ufopFactory;
    @GetMapping("/files/{id}/contents")
    public void getFile(@PathVariable(name = "id") String id, HttpServletResponse response) throws IOException {
        UserFile userFile = userFileService.getById(id);
        if (userFile.isDirectory()){
            throw new DownloadException("非文件格式");
        }
        FileBean fileBean = fileService.getById(userFile.getFileId());
        Downloader downloader = ufopFactory.getDownloader(fileBean.getStorageType());
        if (downloader == null) {
            log.error("下载失败，文件存储类型不支持下载，storageType:{}", fileBean.getStorageType());
            throw new DownloadException("下载失败");
        }
        DownloadFile downloadFile = new DownloadFile();
        downloadFile.setFileUrl(fileBean.getFileUrl());
        InputStream inputStream = downloader.getInputStream(downloadFile);
        ServletOutputStream outputStream = response.getOutputStream();
        IOUtils.copy(inputStream,outputStream);
    }
    @Value("${deployment.host}")
    private String deploymentHost;
    @Value("${server.port}")
    private String port;
    @Autowired
    FileDealComp fileDealComp;
    /**
     * The postFile operation updates a file’s binary contents.
     */
    @PostMapping("/files/{id}/contents")
    public void postFile(@PathVariable(name = "id") String id, @RequestBody byte[] content,
                               HttpServletRequest request) throws IOException {

        UserFile userFile = userFileService.getById(id);
        if (userFile.isDirectory()){
            throw new DownloadException("非文件格式");
        }
        FileBean fileBean = fileService.getById(userFile.getFileId());
        String fileUrl = fileBean.getFileUrl();

        Downloader downloader = ufopFactory.getDownloader(fileBean.getStorageType());
        if (downloader == null) {
            log.error("下载失败，文件存储类型不支持下载，storageType:{}", fileBean.getStorageType());
            throw new DownloadException("下载失败");
        }
        DownloadFile downloadFile = new DownloadFile();
        downloadFile.setFileUrl(fileBean.getFileUrl());
        InputStream inputStream = downloader.getInputStream(downloadFile);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content);
        int fileLength=inputStream.available();
        try {
            fileDealComp.saveFileInputStream(fileBean.getStorageType(), fileUrl, byteArrayInputStream);
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            log.info("当前修改文件大小为：" + (long) fileLength);
            DownloadFile downloadFile2 = new DownloadFile();
            downloadFile2.setFileUrl(fileBean.getFileUrl());
            InputStream inputStream2 = ufopFactory.getDownloader(fileBean.getStorageType()).getInputStream(downloadFile2);
            String md5Str = DigestUtils.md5Hex(inputStream2);
            fileService.updateFileDetail(userFile.getUserFileId(), md5Str, fileLength);
        }
    }

    /**
     * returns information about a file, a user’s permissions on that file,
     * and general information about the capabilities that the WOPI host has on the file.
     */
    @GetMapping("/files/{id}")
    public WOPIFileInfoDTO checkFileInfo(@PathVariable(name = "id") String id,@RequestParam(name = "access_token",required = false)String accessToken) throws Exception {

        boolean canWrite=true;
        if (accessToken.endsWith("preview")) {
            canWrite=false;
            accessToken=accessToken.split("preview")[0];
        }
        String userIdByToken = userService.getUserIdByToken(accessToken);
        if (Strings.isNullOrEmpty(userIdByToken)){
            throw new RuntimeException("access_token invilid");
        }
        UserFile byId = userFileService.getById(id);
        UserBean userBean = userService.getById(byId.getUserId());
        FileDetailVO fileDetail = fileService.getFileDetail(id);
        return (new WOPIFileInfoDTO()
                .setBaseFileName(fileDetail.getFileName()+"."+fileDetail.getExtendName())
                .setSize(fileDetail.getFileSize())
                .setDisableCopy(false)
                //需要权限校验
                .setUserCanWrite(canWrite)
                .setUserFriendlyName(userBean.getUsername())
                .setUserId(userBean.getUserId())
                .setUserExtraInfo(new WOPIFileInfoDTO.UserExtraInfo().setAvatar(userBean.getImageUrl())
                        .setMail(userBean.getEmail()))
        );
    }
}
